package dapps.service.user;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;
import org.springside.modules.orm.hibernate.EntityManager;
import org.springside.modules.security.springsecurity.SpringSecurityUtils;

import dapps.dao.user.DistrictDao;
import dapps.dao.user.UserDao;
import dapps.entity.user.District;
import dapps.entity.user.User;
import dapps.service.ServiceException;

/**
 * 用户管理类.
 * 
 * 实现领域对象用户的所有业务管理函数.
 * 通过范型声明继承EntityManager,默认拥有CRUD管理方法,通过注入的UserDao访问数据库.
 * 演示使用派生DAO子类的模式,数据库访问由UserDao封装.
 * 使用Spring annotation定义事务管理.
 * 
 * @author calvin
 */
@Service
//默认将类中的所有函数纳入事务管理.
@Transactional
public class UserManager extends EntityManager<User, Long> {
	@Autowired
	private UserDao userDao;
	@Autowired
	private DistrictDao dDao;

	@Override
	protected UserDao getEntityDao() {
		return userDao;
	}

	@Override
	public void delete(Long id) {

		//为演示异常处理及用户行为日志而抛出的异常.
		if (id == 1) {
			logger.warn("操作员{}尝试删除超级管理员用户", SpringSecurityUtils.getCurrentUserName());
			throw new ServiceException("不能删除超级管理员用户");
		}

		userDao.delete(id);
	}

	/**
	 * 检查用户名是否唯一.
	 *
	 * @return loginName在数据库中唯一或等于orgLoginName时返回true.
	 */
	@Transactional(readOnly = true)
	public boolean isLoginNameUnique(String loginName, String orgLoginName) {
		return userDao.isPropertyUnique("username", loginName, orgLoginName);
	}

	/**
	 * 查找拥有指定角色的用户.
	 */
	public List<User> getUsersByRole(String roleName) {
		return userDao.getUsersByRole(roleName);
	}
	public List<User> getUsersOrderByRole(String roleName) {
		return userDao.getUsersOrderByRole(roleName);
	}
	
	public Page<User> getCompanypage(Page<User> page,String yearmonth) {
		Criterion[] criterions = {Restrictions.ne("t.tid", 0)
				};		

		String[] alias={"type","t"};
		page.setOrderBy("t.tid,id");
		page.setOrder("asc,asc");
		page = userDao.findByCriteria(page,null, criterions, alias);
		return page;
	}	
	public Page<User> getCompanypage(Page<User> page,Long districtid,String companyname,String companyusername,Integer code) {
		List<Criterion> criterionlist = new ArrayList<Criterion>();
		criterionlist.add(Restrictions.gt("type.tid", 0));//company
		if(districtid!=null&&districtid>0L) criterionlist.add(Restrictions.eq("district.id", districtid));
		if(StringUtils.isNotBlank(companyname)) criterionlist.add(Restrictions.like("name", companyname,MatchMode.ANYWHERE));
		if(StringUtils.isNotBlank(companyusername)) criterionlist.add(Restrictions.like("username", companyusername,MatchMode.ANYWHERE));
		if(code!=null&&code>0L) criterionlist.add(Restrictions.eq("code", code));
		String[] alias={"type","type"};
		if(StringUtils.isBlank(page.getOrderBy())){
			page.setOrderBy("id");page.setOrder("asc");
		}
		Criterion[] ca = criterionlist.toArray(new Criterion[criterionlist.size()]);
		page = userDao.findByCriteria(page,null, ca, alias);
		return page;
	}
	public List<District> getDistrictlist(Criterion[] criterions,String[] alias,Order[] orders) {
		return dDao.findByCriteria(null, criterions, alias, orders);
	}

}
